xend: pass-through: Move pci conversion functions to pci.py
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 17 Jun 2009 06:36:47 +0000 (07:36 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 17 Jun 2009 06:36:47 +0000 (07:36 +0100)
Move dev_dict_to_sxp() into XendSXPDev.py.  Move
pci_convert_dict_to_sxp() and pci_convert_sxp_to_dict() to pci.py,
where other similar functions live.  This makes these functions
accessible outside of the XendConfig class.

Signed-off-by: Simon Horman <horms@verge.net.au>
tools/python/xen/util/pci.py
tools/python/xen/xend/XendConfig.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/XendSXPDev.py [new file with mode: 0644]

index 1ff9652bd3f2c558f7a3e100a941eac1d60ee807..604cff589a7827b2f7b89000883d732279b09f1d 100644 (file)
@@ -14,8 +14,10 @@ import struct
 import time
 import threading
 from xen.util import utils
+from xen.xend import uuid
 from xen.xend import sxp
 from xen.xend.XendConstants import AUTO_PHP_SLOT
+from xen.xend.XendSXPDev import dev_dict_to_sxp
 
 PROC_PCI_PATH = '/proc/bus/pci/devices'
 PROC_PCI_NUM_RESOURCES = 7
@@ -139,6 +141,79 @@ def pci_opts_list_to_sxp(list):
 def pci_opts_list_from_sxp(dev):
     return map(lambda x: sxp.children(x)[0], sxp.children(dev, 'opts'))
 
+def pci_convert_dict_to_sxp(dev, state, sub_state = None):
+    pci_sxp = ['pci', dev_dict_to_sxp(dev), ['state', state]]
+    if sub_state != None:
+        pci_sxp.append(['sub_state', sub_state])
+    return pci_sxp
+
+def pci_convert_sxp_to_dict(dev_sxp):
+    """Convert pci device sxp to dict
+    @param dev_sxp: device configuration
+    @type  dev_sxp: SXP object (parsed config)
+    @return: dev_config
+    @rtype: dictionary
+    """
+    # Parsing the device SXP's. In most cases, the SXP looks
+    # like this:
+    #
+    # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
+    #
+    # However, for PCI devices it looks like this:
+    #
+    # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
+    #
+    # It seems the reasoning for this difference is because
+    # pciif.py needs all the PCI device configurations at
+    # the same time when creating the devices.
+    #
+    # To further complicate matters, Xen 2.0 configuration format
+    # uses the following for pci device configuration:
+    #
+    # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
+
+    # For PCI device hotplug support, the SXP of PCI devices is
+    # extendend like this:
+    #
+    # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
+    #                      [vslot, 0]],
+    #                [state, 'Initialising']]]
+    #
+    # 'vslot' shows the virtual hotplug slot number which the PCI device
+    # is inserted in. This is only effective for HVM domains.
+    #
+    # state 'Initialising' indicates that the device is being attached,
+    # while state 'Closing' indicates that the device is being detached.
+    #
+    # The Dict looks like this:
+    #
+    # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
+    #   states: ['Initialising'] }
+
+    dev_config = {}
+
+    pci_devs = []
+    for pci_dev in sxp.children(dev_sxp, 'dev'):
+        pci_dev_info = dict(pci_dev[1:])
+        if 'opts' in pci_dev_info:
+            pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev)
+        # append uuid to each pci device that does't already have one.
+        if not pci_dev_info.has_key('uuid'):
+            dpci_uuid = pci_dev_info.get('uuid', uuid.createString())
+            pci_dev_info['uuid'] = dpci_uuid
+        pci_devs.append(pci_dev_info)
+    dev_config['devs'] = pci_devs
+
+    pci_states = []
+    for pci_state in sxp.children(dev_sxp, 'state'):
+        try:
+            pci_states.append(pci_state[1])
+        except IndexError:
+            raise XendError("Error reading state while parsing pci sxp")
+    dev_config['states'] = pci_states
+
+    return dev_config
+
 def parse_hex(val):
     try:
         if isinstance(val, types.StringTypes):
index 3b960c773a7568330dfc5063f145979c899f2c7a..41c75da3012700b4f4b6b3bf70bccbd7d3f088bf 100644 (file)
@@ -36,7 +36,8 @@ from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.server.BlktapController import blktap_disk_types
 from xen.xend.server.netif import randomMAC
 from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
-from xen.util.pci import pci_opts_list_from_sxp
+from xen.util.pci import pci_opts_list_from_sxp, pci_convert_sxp_to_dict
+from xen.xend.XendSXPDev import dev_dict_to_sxp
 from xen.util import xsconstants
 import xen.util.auxbin
 
@@ -1295,7 +1296,7 @@ class XendConfig(dict):
                 pci_devs_uuid = sxp.child_value(config, 'uuid',
                                                 uuid.createString())
 
-                pci_dict = self.pci_convert_sxp_to_dict(config)
+                pci_dict = pci_convert_sxp_to_dict(config)
                 pci_devs = pci_dict['devs']
 
                 # create XenAPI DPCI objects.
@@ -1605,79 +1606,6 @@ class XendConfig(dict):
 
         return ''
 
-    def pci_convert_dict_to_sxp(self, dev, state, sub_state = None):
-        pci_sxp = ['pci', self.dev_dict_to_sxp(dev), ['state', state]]
-        if sub_state != None:
-            pci_sxp.append(['sub_state', sub_state])
-        return pci_sxp
-
-    def pci_convert_sxp_to_dict(self, dev_sxp):
-        """Convert pci device sxp to dict
-        @param dev_sxp: device configuration
-        @type  dev_sxp: SXP object (parsed config)
-        @return: dev_config
-        @rtype: dictionary
-        """
-        # Parsing the device SXP's. In most cases, the SXP looks
-        # like this:
-        #
-        # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
-        #
-        # However, for PCI devices it looks like this:
-        #
-        # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
-        #
-        # It seems the reasoning for this difference is because
-        # pciif.py needs all the PCI device configurations at
-        # the same time when creating the devices.
-        #
-        # To further complicate matters, Xen 2.0 configuration format
-        # uses the following for pci device configuration:
-        #
-        # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
-
-        # For PCI device hotplug support, the SXP of PCI devices is
-        # extendend like this:
-        #
-        # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
-        #                      [vslot, 0]],
-        #                [state, 'Initialising']]]
-        #
-        # 'vslot' shows the virtual hotplug slot number which the PCI device
-        # is inserted in. This is only effective for HVM domains.
-        #
-        # state 'Initialising' indicates that the device is being attached,
-        # while state 'Closing' indicates that the device is being detached.
-        #
-        # The Dict looks like this:
-        #
-        # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
-        #   states: ['Initialising'] }
-
-        dev_config = {}
-
-        pci_devs = []
-        for pci_dev in sxp.children(dev_sxp, 'dev'):
-            pci_dev_info = dict(pci_dev[1:])
-            if 'opts' in pci_dev_info:
-                pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev)
-            # append uuid to each pci device that does't already have one.
-            if not pci_dev_info.has_key('uuid'):
-                dpci_uuid = pci_dev_info.get('uuid', uuid.createString())
-                pci_dev_info['uuid'] = dpci_uuid
-            pci_devs.append(pci_dev_info)
-        dev_config['devs'] = pci_devs 
-
-        pci_states = []
-        for pci_state in sxp.children(dev_sxp, 'state'):
-            try:
-                pci_states.append(pci_state[1])
-            except IndexError:
-                raise XendError("Error reading state while parsing pci sxp")
-        dev_config['states'] = pci_states
-
-        return dev_config
-
     def vscsi_convert_sxp_to_dict(self, dev_sxp):
         """Convert vscsi device sxp to dict
         @param dev_sxp: device configuration
@@ -1848,7 +1776,7 @@ class XendConfig(dict):
             dev_type, dev_info = self['devices'][dev_uuid]
 
             if dev_type == 'pci': # Special case for pci
-                pci_dict = self.pci_convert_sxp_to_dict(config)
+                pci_dict = pci_convert_sxp_to_dict(config)
                 pci_devs = pci_dict['devs']
 
                 # destroy existing XenAPI DPCI objects
@@ -1971,15 +1899,6 @@ class XendConfig(dict):
         result.extend([u for u in target['devices'].keys() if u not in result])
         return result
 
-    # This includes a generic equivalent of pci_opts_list_to_sxp()
-    def dev_dict_to_sxp(self, dev):
-        def f((key, val)):
-            if isinstance(val, types.ListType):
-                return map(lambda x: [key, x], val)
-            return [[key, val]]
-        dev_sxp = ['dev'] + reduce(lambda x, y: x + y, map(f, dev.items()))
-        return dev_sxp
-
     def all_devices_sxpr(self, target = None):
         """Returns the SXPR for all devices in the current configuration."""
         sxprs = []
@@ -2002,7 +1921,7 @@ class XendConfig(dict):
                     if dev_info.has_key('backend'):
                         sxpr.append(['backend', dev_info['backend']])
                 for pci_dev_info in dev_info['devs']:
-                    sxpr.append(self.dev_dict_to_sxp(pci_dev_info))
+                    sxpr.append(dev_dict_to_sxp(pci_dev_info))
                 sxprs.append((dev_type, sxpr))
             else:
                 sxpr = self.device_sxpr(dev_type = dev_type,
index 2c283e3d7b937f9f06f524edbc13aef41d949e5a..0e77023e0397b905f7ec3815c8209dc01c757a01 100644 (file)
@@ -40,7 +40,9 @@ from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
 import xen.util.xsm.xsm as security
 from xen.util import xsconstants
 from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
-                         pci_dict_to_bdf_str, pci_dict_to_xc_str, pci_dict_cmp
+                         pci_dict_to_bdf_str, pci_dict_to_xc_str, \
+                         pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \
+                         pci_dict_cmp
 
 from xen.xend import balloon, sxp, uuid, image, arch
 from xen.xend import XendOptions, XendNode, XendConfig
@@ -616,8 +618,8 @@ class XendDomainInfo:
         pci_conf = self.info['devices'][dev_uuid][1]
         pci_devs = pci_conf['devs']
         request = map(lambda x:
-                      self.info.pci_convert_dict_to_sxp(x, 'Initialising',
-                                                        'Booting'), pci_devs)
+                      pci_convert_dict_to_sxp(x, 'Initialising', 'Booting'),
+                      pci_devs)
 
         for i in request:
                 self.pci_device_configure(i)
@@ -815,7 +817,7 @@ class XendDomainInfo:
             raise XendError("Cannot detach when pci platform does not exist")
 
         pci_dev = sxp.children(dev_sxp, 'dev')[0]
-        dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp)
+        dev_config = pci_convert_sxp_to_dict(dev_sxp)
         dev = dev_config['devs'][0]
                 
         # Do HVM specific processing
diff --git a/tools/python/xen/xend/XendSXPDev.py b/tools/python/xen/xend/XendSXPDev.py
new file mode 100644 (file)
index 0000000..dac5e6c
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+#
+# Helper functions for dealing with the sxp representation of devices
+
+import types
+
+# This includes a generic equivalent of pci_opts_list_to_sxp()
+def dev_dict_to_sxp(dev):
+    def f((key, val)):
+        if isinstance(val, types.ListType):
+            return map(lambda x: [key, x], val)
+        return [[key, val]]
+    dev_sxp = ['dev'] + reduce(lambda x, y: x + y, map(f, dev.items()))
+    return dev_sxp